package com.jy.modules.cims.creditright.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.exception.CimsException;
import com.jy.modules.cims.common.sysUtils.CollectionsUtils;
import com.jy.modules.cims.common.sysUtils.DateTimeUtils;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.common.sysUtils.SimpleBeanUtils;
import com.jy.modules.cims.common.sysUtils.SimpleStringUtils;
import com.jy.modules.cims.common.sysUtils.SpringContextUtils;
import com.jy.modules.cims.component.common.service.TCMmCooperorgDealReleService;
import com.jy.modules.cims.component.common.service.TCMmCreditPackageService;
import com.jy.modules.cims.component.creditRight.plan.CreditPlanConstant;
import com.jy.modules.cims.component.sysAssist.CSysAssistImpl;
import com.jy.modules.cims.component.sysAssist.TaskLogImpl;
import com.jy.modules.cims.contract.service.ContractService;
import com.jy.modules.cims.data.common.dao.TCMmCooperorgDealReleDao;
import com.jy.modules.cims.data.common.dto.TCMmCooperorgDealReleDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditPackageDTO;
import com.jy.modules.cims.data.common.dto.TCMmTaskLogDTO;
import com.jy.modules.cims.data.dao.CreditRightDao;
import com.jy.modules.cims.data.dao.DealDao;
import com.jy.modules.cims.data.dto.ContractAllDto;
import com.jy.modules.cims.data.dto.CreditDetailDto;
import com.jy.modules.cims.data.dto.CreditDetailQueryDto;
import com.jy.modules.cims.data.dto.CreditPackageDto;
import com.jy.modules.cims.data.dto.DealDto;
import com.jy.modules.cims.data.dto.QuotaDetailUnlockParamDto;
import com.jy.modules.cims.data.dto.credit.PublicSettleParamDto;
import com.jy.modules.cims.deal.service.DealService;
import com.jy.modules.cims.interact.CCInteractImpl;
import com.jy.modules.cims.interact.ICInteract;
import com.jy.modules.cims.sysassist.SysAssistService;
import com.jy.platform.api.org.SessionAPI;

@Service("com.jy.modules.cims.creditright.service.SettleAndSecondBuyService")
public class SettleAndSecondBuyService {
	private static final Logger logger = LoggerFactory.getLogger(SettleAndSecondBuyService.class);
	
	// 正常/异常月还的交易类型
	private String[] dealTypes = { CimsConstant.DEAL_TYPE_MONTH_BACK, CimsConstant.DEAL_TYPE_CREDIT_SETTLE, CimsConstant.DEAL_TYPE_LOAN_MONTH_BACK, CimsConstant.DEAL_TYPE_LOAN_CREDIT_SETTLE,
			CimsConstant.DEAL_TYPE_CREDIT_NORMAL_SETTLE_REC, CimsConstant.DEAL_TYPE_CREDIT_ABNORMAL_SETTLE_REC };

	// 异常月还的结算计划变更类型
	private String[] changeTypes = { CreditPlanConstant.CHANGE_TYPE_CHANGEDATE, CreditPlanConstant.CHANGE_TYPE_ADVANCEREPAY, CreditPlanConstant.CHANGE_TYPE_OVERDUE,
			CreditPlanConstant.CHANGE_TYPE_ADVANCEFINISH, CreditPlanConstant.CHANGE_TYPE_CANCEL, CreditPlanConstant.CHANGE_TYPE_ROLLFINISH, CreditPlanConstant.CHANGE_TYPE_ANEW,
			CreditPlanConstant.CHANGE_TYPE_DELAY, CreditPlanConstant.CHANGE_TYPE_FORCEFINISH };
	
	
	@Autowired
	private CreditRightDao creditRightDao;
	
	@Autowired
	public DealDao dealDao;
	
	@Autowired
	private SpringContextUtils springContextUtils;
	
	@Autowired
	private SessionAPI sessionAPI;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.contract.service.ContractService")
	private ContractService contractService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.creditright.service.SecondBuyCreditService")
	private SecondBuyCreditService secondBuyCreditService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.sysassist.SysAssistService")
	private SysAssistService sysAssistService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.deal.service.DealService")
	public DealService dealService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditPackageService")
	private TCMmCreditPackageService creditPackageService;
	
	@Autowired
	@Qualifier("com.jy.modules.platform.tcmmcooperorgdealrele.service.TCMmCooperorgDealReleService")
	private TCMmCooperorgDealReleService cooperorgDealReleService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.sysAssist.CSysAssistImpl")
	private CSysAssistImpl csysAssistimpl;
	
	
	/**
	 * @description 查询符合结算的债权包信息
	 * @author shengzhoutao
	 * @param creditPackageDto
	 *            债权包信息
	 * @return
	 */
	public List<CreditPackageDto> searchCreditPackageForSettle(final CreditPackageDto creditPackageDto) {
		List<CreditPackageDto> creditPackageDtoList = creditRightDao.searchCreditPackageForSettle(SearchParamUtil.getSearchParam(creditPackageDto));

		return creditPackageDtoList;
	}

	/**
	 * @description 查询符合结算的债权包信息
	 * @author shengzhoutao
	 * @param cooperorgCode
	 *            机构编号
	 * @param contractCode
	 *            合约编号
	 * @param creditPackageName
	 *            债权包
	 * @param settleDate
	 *            结算日期
	 * @return
	 */
	public List<CreditPackageDto> searchCreditPackageForSettle(final String cooperorgCode, final String contractCode, final String creditPackageName,
			final String settleDate) {
		CreditPackageDto newCreditPackageDto = new CreditPackageDto();
		newCreditPackageDto.setCooperorgCode(cooperorgCode);
		newCreditPackageDto.setContractCode(contractCode);
		newCreditPackageDto.setCreditPackageName(creditPackageName);
		newCreditPackageDto.setSettleDate(settleDate);

		return searchCreditPackageForSettle(newCreditPackageDto);
	}

	/**
	 * @description 批量结算和(历史结算流水+新生成流水)二次购买。 新增/保存债权购买(二次购买匹配债权)结果。
	 * @author shengzhoutao
	 * @param creditPackage
	 * @param hisSettleDealDtoList
	 * @param creditDetailQueryDtoList
	 * @return
	 * @throws Exception
	 */
	public DealDto doSettleAndSecondBuy(CreditPackageDto creditPackage, List<DealDto> hisSettleDealDtoList,
			List<CreditDetailQueryDto> creditDetailQueryDtoList) throws Exception {

		// 处理月还结算
		List<DealDto> settleDealDtoList = dealSettle(creditPackage, hisSettleDealDtoList, creditDetailQueryDtoList);

		// 处理债权购买(二次购买匹配债权)结果
		DealDto secondBuyDealDto = dealSecondBuy(creditPackage, settleDealDtoList);

		return secondBuyDealDto;
	}
	
	/**
	 * @description 处理月还
	 * @author shengzhoutao
	 * @param creditPackage
	 *            债权包
	 * @param hisSettleDealDtoList
	 *            历史已经结算的流水
	 * @param creditDetailQueryDtoList
	 *            将要生成新的结算参数
	 * @return settleDealDtoList 结算的流水
	 * @throws Exception
	 */
	public List<DealDto> dealSettle(CreditPackageDto creditPackage, List<DealDto> hisSettleDealDtoList,
			List<CreditDetailQueryDto> creditDetailQueryDtoList) throws Exception {

		List<DealDto> settleDealDtoList = new ArrayList<DealDto>();
		List<DealDto> newSettleDealDtoList = null;

		if (CollectionsUtils.isNotEmpty(creditDetailQueryDtoList)) {
			List<String> settleDealCodeList = new ArrayList<String>();// 定义结算流水号
			SettleCreditService settleCreditService = springContextUtils.getBean(SettleCreditService.class);

			for (CreditDetailQueryDto creditDetailQueryDto : creditDetailQueryDtoList) {
				logger.info("调用正常结算/异常结算方法===>>>");
				// 调用正常结算/异常结算交易方法，返回结算交易流水号
				creditDetailQueryDto.setBatchFlag(true);
				String dealCode = settleCreditService.doSettle(creditDetailQueryDto);
				if (SimpleStringUtils.hasText(dealCode)
						&& !CimsConstant.DEAL_TYPE_CREDIT_NORMAL_SETTLE_REC.equals(creditDetailQueryDto.getDealType())) {
					settleDealCodeList.add(dealCode);
				}
			}

			if (CollectionsUtils.isNotEmpty(settleDealCodeList)) {
				// 根据结算交易流水号批量查询交易流水信息的详细信息
				newSettleDealDtoList = springContextUtils.getBean(DealDao.class).getCooperorgDealByDealCodeList(settleDealCodeList);
				logger.info("新生成结算的流水个数：" + newSettleDealDtoList.size());
			}
			settleDealCodeList = null;
		}

		if (CollectionsUtils.isNotEmpty(hisSettleDealDtoList)) {
			logger.info("历史已结算的流水个数：" + hisSettleDealDtoList.size());
			settleDealDtoList = CollectionsUtils.union(settleDealDtoList, hisSettleDealDtoList);
		}
		if (CollectionsUtils.isNotEmpty(newSettleDealDtoList)) {
			settleDealDtoList = CollectionsUtils.union(settleDealDtoList, newSettleDealDtoList);
		}

		return settleDealDtoList;
	}
	
	/**
	 * @description 保存债权购买(二次购买匹配债权)结果
	 * @author shengzhoutao
	 * @param creditPackage
	 *            债权包
	 * @param settleDealDtoList
	 *            月还交易流水集合
	 * @return DealDto 生成的二次购买流水的对象
	 * @throws Exception
	 */
	public DealDto dealSecondBuy(final CreditPackageDto creditPackage, List<DealDto> settleDealDtoList) throws Exception {
		List<String> newSettleDealCodeList = new ArrayList<String>();// 定义待购买的流水的集合
		// 待购买的流水可以二次购买，去掉已购买的结算交易流水号
		for (DealDto dealDto : settleDealDtoList) {
			if (CimsConstant.DEAL_STATUS_MONTH_BACK.equals(dealDto.getCooperativeAgencyDealStatus())) {// 合作机构交易状态:04-待购买
				newSettleDealCodeList.add(dealDto.getDealCode());
			}
		}
		logger.info("待购买的流水个数：" + newSettleDealCodeList.size());

		// 待购买的流水，二次购买
		if (CollectionsUtils.isEmpty(newSettleDealCodeList)) {
			return null;
		}

		String cooperorgCode = creditPackage.getCooperorgCode();
		String creditPackageName = creditPackage.getCreditPackageName();
		String contractCode = creditPackage.getContractCode();
		logger.info("合作机构编号:::" + cooperorgCode);
		logger.info("合约编号:::" + contractCode);
		logger.info("债权包名称:::" + creditPackageName);

		String productType = "";// 产品类型

		// 通过合约号获取合约相关信息
		ContractAllDto contractAllDto = contractService.getContractAllInfo(creditPackage.getContractCode());
		if (null == contractAllDto || null == contractAllDto.getCdto()) {
			throw new CimsException("没有查询到合约编号:" + creditPackage.getContractCode() + "的信息");
		}

		DealDto dealDto = new DealDto();

		String secondContractCode = contractAllDto.getCdto().getSecondCode();// 二次购买匹配债权的合约
		String secondPagSuffix = contractAllDto.getCdto().getSecondPagSuffix();// 二次购买匹配债权的包后缀
		productType = contractAllDto.getCdto().getProductType();// 产品类型

		if (SimpleStringUtils.hasText(secondContractCode) && SimpleStringUtils.hasText(secondPagSuffix)) {
			contractCode = secondContractCode;
			creditPackageName = creditPackageName + secondPagSuffix;
			ContractAllDto secondContract = contractService.getContractAllInfo(secondContractCode);
			productType = (null != secondContract && null != secondContract.getCdto()) ? secondContract.getCdto().getProductType() : productType;
		}

		dealDto.setCooperorgCode(cooperorgCode);// 合作机构
		dealDto.setContractCode(contractCode);// 合约编号
		dealDto.setAgreementCode(contractAllDto.getAgreementDTO().getAgreementCode());// 协议编号
		dealDto.setCreditPackageName(creditPackageName);// 债权包
		dealDto.setProductType(productType);

		// 批量查询月还交易信息
		List<DealDto> secondBuySettleDealDtoList = dealDao.getCooperorgDealByDealCodeList(newSettleDealCodeList);

		// 新增债权包
		dealDto = insertCreditPackage(dealDto);

		// 新增二次购买交易流水
		dealDto = insertSecondBuyDeal(dealDto, secondBuySettleDealDtoList);

		// 在系统管理-》参数管理，配置是否延用挑选债权旧服务（Y：是；N：否）：oldAutoOptionCredit
		String oldAutoOptionCredit = csysAssistimpl.getSysConfigValueByCode("oldAutoOptionCredit");
		// 保存挑选债权结果
		if (CimsConstant.FLAG_YES.equalsIgnoreCase(oldAutoOptionCredit)) {
//			secondBuyCreditService.doAutoOptionCredit(dealDto);
			secondBuyCreditService.doAutoPretendCredit(dealDto);
		} else {
			// this.doAutoOptionCredit(dealDto);
//			secondBuyCreditService.doAutoOptionCredit(dealDto);
			secondBuyCreditService.doAutoPretendCredit(dealDto);
		}

		// 批量修改月还结算和债权结算待购买的交易流水的交易状态
		dealService.updateDealStatusByDealCodeList(CimsConstant.DEAL_STATUS_SECOND_PURCHASE, newSettleDealCodeList);// 05-已购买

		return dealDto;
	}

	/**
	 * @description 确认债权购买(二次购买)结果
	 * @param dealDto
	 * @throws Exception
	 */
	public void confirmSecondBuy(DealDto dealDto) {
		try {
			// 在系统管理-》参数管理，配置自动确认二次购买标示（Y：是；N：否）：autoConfrirmSecondBuy
			String autoConfrirmSecondBuy = csysAssistimpl.getSysConfigValueByCode("autoConfrirmSecondBuy");// 自动确认二次购买标示
			if (!CimsConstant.FLAG_YES.equalsIgnoreCase(autoConfrirmSecondBuy)) {
				return;
			}
			dealDto.setRepaymentAffiliation("0");
			secondBuyCreditService.doConfirmSecondBuyCredit(dealDto);
		} catch (Exception e) {
			logger.error("确认债权购买(二次购买)结果出错:" + e);
		}
	}
	
	/**
	 * @description 过滤可生成结算
	 * @author shengzhoutao
	 * @param creditDetailQueryDtoList
	 * @return
	 * @throws Exception
	 */
	public List<CreditDetailQueryDto> filterCreditDetailQueryDtoList(final List<CreditDetailQueryDto> creditDetailQueryDtoList) throws Exception {
		List<CreditDetailQueryDto> newCreditDetailQueryDtoList = new ArrayList<CreditDetailQueryDto>();
		CreditDetailQueryDto newCreditDetailQueryDto = null;
		SettleCreditService settleCreditService = springContextUtils.getBean(SettleCreditService.class);
		for (CreditDetailQueryDto creditDetailQueryDto : creditDetailQueryDtoList) {
			creditDetailQueryDto.setBatchFlag(true);
			// 遍历交易类型
			for (String dealType : dealTypes) {
				creditDetailQueryDto.setDealType(dealType);
				if (CimsConstant.DEAL_TYPE_CREDIT_SETTLE.equals(dealType) || CimsConstant.DEAL_TYPE_LOAN_CREDIT_SETTLE.equals(dealType)) {
					// 遍历异常类型
					for (String changeType : changeTypes) {
						creditDetailQueryDto.setPlanStatus(changeType);
						// 查询所有符合结算的债权明细
						List<CreditDetailDto> creditDetailDtoList = settleCreditService.searchCreditDetailForSettle(creditDetailQueryDto);
						if (CollectionsUtils.isNotEmpty(creditDetailDtoList)) {
							newCreditDetailQueryDto = new CreditDetailQueryDto();
							SimpleBeanUtils.copyBean2Bean(newCreditDetailQueryDto, creditDetailQueryDto);
							newCreditDetailQueryDtoList.add(newCreditDetailQueryDto);
							newCreditDetailQueryDto = null;
						}
					}
				} else {
					creditDetailQueryDto.setPlanStatus(null);
					// 查询所有符合结算的债权明细
					List<CreditDetailDto> creditDetailDtoList = settleCreditService.searchCreditDetailForSettle(creditDetailQueryDto);
					if (CollectionsUtils.isNotEmpty(creditDetailDtoList)) {
						newCreditDetailQueryDto = new CreditDetailQueryDto();
						SimpleBeanUtils.copyBean2Bean(newCreditDetailQueryDto, creditDetailQueryDto);
						newCreditDetailQueryDtoList.add(newCreditDetailQueryDto);
						newCreditDetailQueryDto = null;
					}
				}
			}
		}
		logger.info("过滤前可生成结算的个数：" + creditDetailQueryDtoList.size());
		logger.info("过滤后可生成结算的个数：" + newCreditDetailQueryDtoList.size());
		return newCreditDetailQueryDtoList;
	}

	/**
	 * @description 删除/重置已经结算记录和关联的二次购买记录，其它数据恢复到未结算前的数据。
	 * @author shengzhoutao
	 * @param cooperorgCode
	 *            机构编号，必须输入项
	 * @param contractCode
	 *            合约编号，必须输入项
	 * @param creditPackageName
	 *            债权包名称，必须输入项
	 * @param settleDateStr
	 *            结算日期，必须输入项，格式：yyyy-MM-dd
	 * @param checkTaskLog
	 * @throws Exception
	 */
	public void deleteSettleAndSecondBuy(final String cooperorgCode, final String contractCode, final String creditPackageName, final String settleDateStr, Boolean checkTaskLog) throws Exception {
		logger.info("删除/重置已经结算记录和关联的二次购买记录，其它数据恢复到未结算前的数据 begin>>>>>");
		logger.info("机构编号:::" + cooperorgCode);
		logger.info("合约编号:::" + contractCode);
		logger.info("债权包名称:::" + creditPackageName);
		logger.info("结算日期:::" + settleDateStr);

		Date settleDate = DateTimeUtils.parse(settleDateStr, "yyyy-MM-dd");// 结算日期

		if (checkTaskLog == true) {
			// 查询日志修改，修改日志记录.
			TaskLogImpl taskLogImpl = springContextUtils.getBean(TaskLogImpl.class);
			List<TCMmTaskLogDTO> tcmmTaskLogDTOList = taskLogImpl.searchTCMmTaskLog(cooperorgCode, contractCode, creditPackageName, settleDateStr);
			if (CollectionsUtils.isNotEmpty(tcmmTaskLogDTOList)) {
				for (TCMmTaskLogDTO updateTCMmTaskLogDTO : tcmmTaskLogDTOList) {
					taskLogImpl.updateTCMmTaskLogExeStatus(updateTCMmTaskLogDTO.getId(), CimsConstant.EXE_STATUS_UNPROCESSED, "");
				}
			} else {
				logger.info("日志无记录，不需要重置。");
				return;
			}
		}

		// 根据合作机构编号，合约编码，债权包，结算日期，查询结算流水信息.
		List<DealDto> settleDealDtoList = getCooperorgDealBySettle(cooperorgCode, contractCode, creditPackageName, settleDateStr);
		if (CollectionsUtils.isEmpty(settleDealDtoList)) {
			logger.info("根据合作机构编号，合约编码，债权包，结算日期，没有查询到符合条件的结算流水信息。");
			return;
		}

		List<String> dealCodeList = new ArrayList<String>();
		for (DealDto settleDealDto : settleDealDtoList) {
			String settleDealCode = settleDealDto.getDealCode();
			logger.info("结算流水号:::" + settleDealCode);
			dealCodeList.add(settleDealCode);
		}

		CreditRightDao creditRightDao = springContextUtils.getBean(CreditRightDao.class);
		// 循环迭代结算流水信息
		DealDto settleDealDto = null;
		for (String settleDealCode : dealCodeList) {
			settleDealDto = new DealDto();
			settleDealDto.setDealCode(settleDealCode);
			settleDealDto.setSettleDate(settleDate);
			// 月还重置债权信息：修改债权状态已转让, 修改剩余还款期数减一.
			creditRightDao.updateCreditDetailForResetSettle(SearchParamUtil.getSearchParam(settleDealDto));

			// 月还重置结算计划信息：修改结算状态未结算.
			creditRightDao.updateCostPlanForResetSettle(SearchParamUtil.getSearchParam(settleDealDto));

			// 根据交易流水号批量删除债权交易流水表明细.
			creditRightDao.deleteCreditDealDetailByDealCode(SearchParamUtil.getSearchParam(settleDealDto));
		}
		// 。。。。。。。。。。。。。。。。。。
		// ///////////////////////////////////

		// 处理二次购买的相关信息。。。。。。
		DealDto secondBuyDeal = new DealDto();
		secondBuyDeal.setDealCodeList(dealCodeList);
		// 根据结算流水去查询二次购买流水，
		List<String> secondBuyDealCodeList = creditRightDao.getSecondBuyDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));
		if (CollectionsUtils.isNotEmpty(secondBuyDealCodeList)) {
			for (String secondBuyDealCode : secondBuyDealCodeList) {
				logger.info("二次购买流水号:::" + secondBuyDealCode);
				// 根据二次购买的流水查询匹配的债权明细
				secondBuyDeal = new DealDto();
				secondBuyDeal.setDealCode(secondBuyDealCode);
				secondBuyDeal.setSettleDate(settleDate);

				// 删除二次购买
				deleteSecondBuy(secondBuyDeal);
			}
		}

		// 。。。。。。。。。。。。。
		// /////////////////////////////

		// 删除正常结算和异常结算(已购买,待购买)的合作机构交易流水表
		for (DealDto delDealDto : settleDealDtoList) {
			// 根据交易流水号删除正常结算和异常结算(已购买,待购买)的合作机构交易流水表
			creditRightDao.deleteCooperorgDealByDealCode(SearchParamUtil.getSearchParam(delDealDto));
		}

		secondBuyDeal = null;
		logger.info("删除/重置已经结算记录和关联的二次购买记录，其它数据恢复到未结算前的数据 end>>>>>");
		settleDealDtoList = null;
	}

	
	/**
	 * 删除二次购买
	 * @author shengzhoutao
	 * @param dealDto
	 */
	public void deleteSecondBuy(DealDto dealDto){
		logger.info("二次购买流水号:::" + dealDto.getDealCode());
		
		// 根据二次购买的流水查询匹配的债权明细
		DealDto secondBuyDeal = new DealDto();
		secondBuyDeal.setDealCode(dealDto.getDealCode());
		List<CreditDetailDto> creditDetailDtoList = dealDao.getDealDetailByCreditList(SearchParamUtil.getSearchParam(secondBuyDeal));

		// 释放匹配的债权明细
		unlockQuotaCreditDetail(creditDetailDtoList, dealDto.getSettleDate());
					
		// 根据交易流水号删除二次购买的合作机构交易流水表
		// 删除债权明细
		creditRightDao.deleteCreditDetailByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));
		// 删除债权明细流水
		creditRightDao.deleteCreditDealDetailByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));
		// 删除二次购买的流水
		creditRightDao.deleteCooperorgDealByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));

		// 删除二次购买关联的交易流水号记录
		creditRightDao.deleteCooperorgDealReleByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));	
	}
	
	/**
	 * @description 删除已经结算记录记录，其它数据恢复到未结算前的数据。
	 * @author shengzhoutao
	 * @param dealCode
	 *            交易流水号
	 * @throws Exception
	 */
	public void deleteSettle(final String dealCode) throws Exception {
		logger.info("删除已经结算记录和关联的二次购买记录，其它数据恢复到未结算前的数据 begin>>>>>");
		logger.info("机构编号:::" + dealCode);

		List<DealDto> dealDtoList = springContextUtils.getBean(DealService.class).getCooperorgDealByDealCodeStr(dealCode);
		if (CollectionsUtils.isEmpty(dealDtoList)) {
			return;
		}

		CreditRightDao creditRightDao = springContextUtils.getBean(CreditRightDao.class);

		DealDto settleDealDto = dealDtoList.get(0);

		// 月还重置债权信息：修改债权状态已转让, 修改剩余还款期数减一.
		creditRightDao.updateCreditDetailForResetSettle(SearchParamUtil.getSearchParam(settleDealDto));

		// 月还重置结算计划信息：修改结算状态未结算.
		creditRightDao.updateCostPlanForResetSettle(SearchParamUtil.getSearchParam(settleDealDto));

		// 根据交易流水号批量删除债权交易流水表明细.
		creditRightDao.deleteCreditDealDetailByDealCode(SearchParamUtil.getSearchParam(settleDealDto));

		// 删除正常结算和异常结算(已购买,待购买)的合作机构交易流水表
		// 根据交易流水号删除正常结算和异常结算(已购买,待购买)的合作机构交易流水表
		creditRightDao.deleteCooperorgDealByDealCode(SearchParamUtil.getSearchParam(settleDealDto));

		logger.info("删除已经结算记录，其它数据恢复到未结算前的数据 end>>>>>");
	}

	/**
	 * @description 删除已经结算记录和关联的二次购买记录，其它数据恢复到未结算前的数据。
	 * @author shengzhoutao
	 * @param dealCode
	 *            交易流水号
	 * @throws Exception
	 */
	public void deleteSecondBuy(final String dealCode) throws Exception {
		
		logger.info("删除已经结算记录和关联的二次购买记录，其它数据恢复到未结算前的数据 begin>>>>>");
		logger.info("机构编号:::" + dealCode);
		
		List<DealDto> dealDtoList = springContextUtils.getBean(DealService.class).getCooperorgDealByDealCodeStr(dealCode);
		if (CollectionsUtils.isEmpty(dealDtoList)) {
			return;
		}

		CreditRightDao creditRightDao = springContextUtils.getBean(CreditRightDao.class);
		DealDao dealDao = springContextUtils.getBean(DealDao.class);
		TCMmCooperorgDealReleDao cooperorgDealReleDao = springContextUtils.getBean(TCMmCooperorgDealReleDao.class);

		DealDto dealDto = dealDtoList.get(0);


		// 处理二次购买的相关信息。。。。。。
		List<CreditDetailDto> creditDetailDtoList = null;

		// 根据二次购买的流水查询匹配的债权明细
		DealDto secondBuyDeal = new DealDto();
		secondBuyDeal.setDealCode(dealCode);
		creditDetailDtoList = dealDao.getDealDetailByCreditList(SearchParamUtil.getSearchParam(secondBuyDeal));
		
		//调用二次购买撤销结构
		this.secondBuyReturn(dealDto,creditDetailDtoList);
		
		
		// 根据查询结算流水信息.
		TCMmCooperorgDealReleDTO cooperorgDealReleDTO = new TCMmCooperorgDealReleDTO();
		cooperorgDealReleDTO.setDealCode(dealCode);
		List<TCMmCooperorgDealReleDTO> cooperorgDealReleDTOList = cooperorgDealReleDao.searchTCMmCooperorgDealRele(SearchParamUtil
				.getSearchParam(cooperorgDealReleDTO));
		if (CollectionsUtils.isNotEmpty(cooperorgDealReleDTOList)) {
			for (TCMmCooperorgDealReleDTO releDTO : cooperorgDealReleDTOList) {
				// 删除已经结算记录记录，其它数据恢复到未结算前的数据。
				deleteSettle(releDTO.getOldDealCode());
			}
		}
		
		if (CollectionsUtils.isNotEmpty(creditDetailDtoList)) {
			// 释放匹配的债权明细
			unlockQuotaCreditDetail(creditDetailDtoList, dealDto.getSettleDate());
		}

		// 根据交易流水号删除二次购买的合作机构交易流水表
		// 删除债权明细
		creditRightDao.deleteCreditDetailByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));
		// 删除债权明细流水
		creditRightDao.deleteCreditDealDetailByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));
		// 删除二次购买的流水
		creditRightDao.deleteCooperorgDealByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));

		// 删除二次购买关联的交易流水号记录
		creditRightDao.deleteCooperorgDealReleByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));

		// 删除正常结算和异常结算(已购买,待购买)的合作机构交易流水表
		// 根据交易流水号删除正常结算和异常结算(已购买,待购买)的合作机构交易流水表
		creditRightDao.deleteCooperorgDealByDealCode(SearchParamUtil.getSearchParam(secondBuyDeal));	
	}
	
	/**
	 * 
	 * @Description 二次购买撤销-接口调用
	 * @param dealCode
	 * @param creditDetailDtoList   
	 * void  
	 * @throws
	 * @author zhangmi
	 * @date 2016-7-19
	 */
	public void secondBuyReturn(DealDto dealDto,List<CreditDetailDto> creditDetailDtoList){
		
		ICInteract iCInteract = springContextUtils.getBean(com.jy.modules.cims.interact.CCInteractImpl.class);
		CreditRightDao creditRightDao = springContextUtils.getBean(CreditRightDao.class);
//		SecondBuyCreditService secondBuyCreditService = springContextUtils.getBean(SecondBuyCreditService.class);
		
		
		if (CollectionsUtils.isEmpty(creditDetailDtoList)) {
			return;
		}
		String dealCode = dealDto.getDealCode();
		
		// 如果根据二次购买关联合约查询有数据，则是贷款转出匹配债权，否则是债权转让匹配债权
		boolean isAllQrFlag = true;
		for (CreditDetailDto creditDetailDto : creditDetailDtoList) {
			//如果存在不是在途
			if(!CimsConstant.CREDIT_STATUS_WAY.equals(creditDetailDto.getCreditorStatus())){
				isAllQrFlag = false;
				break;
			}
		}
		
		if(!isAllQrFlag){//有非在途
			isAllQrFlag = true;//恢复到正常
			for (CreditDetailDto creditDetailDto : creditDetailDtoList) {
				//如果存在不是已确认
				if(!CimsConstant.CREDIT_STATUS_WIN.equals(creditDetailDto.getCreditorStatus())){
					isAllQrFlag = false;
					break;
				}
			}
			if(!isAllQrFlag){
				throw new CimsException("只有全部为‘在途’或‘已确认’才能删除");
			}else{//全部是已确认
				//验证是贷款的二次购买。还是债权的二次购买。
//				if (secondBuyCreditService.checkDealTypeForSecondBuy(dealCode)) {
//					throw new CimsException("贷款二次购买新匹配债权,“已确认”状态的债权不可以删除/重置！");
//				}else{//债权二次购买并且状态为：已确认
				CreditDetailDto isCredit =null;
				DealDto searchAppId = new DealDto();
				searchAppId.setDealCode(dealCode);
				List<CreditDetailDto> listAppid = creditRightDao.getSecondSettleApplyIdByDealCode(SearchParamUtil.getSearchParam(searchAppId));
				if(CollectionsUtils.isEmpty(listAppid)){
					throw new CimsException("没有月还结算信息,未获取到结算申请编号，结算日期！");
				}else{
					isCredit = listAppid.get(0);
					if(null==isCredit.getSettleDate()){
						throw new CimsException("交易流水号"+dealCode+"结算日期为空！");
					}
					if(!SimpleStringUtils.hasText(isCredit.getSettleApplyId())){
						throw new CimsException("交易流水号"+dealCode+"结算编号为空！");
					}
				}
				String nowTime = DateTimeUtils.getDateTime(DateTimeUtils.DEFAULT_DATE_FORMAT);
				String settlesTime = DateTimeUtils.formatDate(dealDto.getDealDate(), DateTimeUtils.DEFAULT_DATE_FORMAT);
				if(nowTime.equals(settlesTime)){//判断日期是否为当天
					PublicSettleParamDto publicSettleParamDto=new PublicSettleParamDto();
					publicSettleParamDto.setApplyCode(isCredit.getSettleApplyId());//撤销批次编号
					publicSettleParamDto.setApplyName(sessionAPI.getCurrentUserInfo()==null?"管理员":sessionAPI.getCurrentUserInfo().getUserName());//申请人姓名
					publicSettleParamDto.setDealCode(dealCode);
					logger.info(" 调用4046二次购买撤销接口，撤销批次号为"+isCredit.getSettleApplyId()+">>>>>");
					iCInteract.sendTwoCreditBuyReturn(publicSettleParamDto);
					logger.info("“二次购买已确认状态”撤销接口调用成功！>>>>>");
				}else{
					throw new CimsException("交易日期和删除日期必须是当天！");
				}
//				}
			}
		}else {//全部在途
			logger.info("“二次购买在途状态”不做处理-模拟调用撤销接口成功！>>>>>");
		}
		
	}

	/**
	 * @description 根据合作机构编号，合约编码，债权包，结算日期，查询结算流水信息
	 * @param cooperorgCode
	 * @param contractCode
	 * @param creditPackageName
	 * @param settleDate
	 * @return
	 */
	public List<DealDto> getCooperorgDealBySettle(final String cooperorgCode, final String contractCode, final String creditPackageName,
			final String settleDate) {
		DealDao dealDao = springContextUtils.getBean(DealDao.class);
		DealDto dealDto = new DealDto();
		dealDto.setCooperorgCode(cooperorgCode);
		dealDto.setContractCode(contractCode);
		dealDto.setCreditPackageName(creditPackageName);
		dealDto.setSettleDate(DateTimeUtils.parse(settleDate, "yyyy-MM-dd"));
		return dealDao.getCooperorgDealBySettle(SearchParamUtil.getSearchParam(dealDto));
	}

	/**
	 * @description
	 * @param creditDetailDtoList
	 * @param settleDate
	 */
	private void unlockQuotaCreditDetail(final List<CreditDetailDto> creditDetailDtoList, final Date settleDate) {
		if (CollectionsUtils.isEmpty(creditDetailDtoList)) {
			return;
		}

		CCInteractImpl interactImpl = springContextUtils.getBean(CCInteractImpl.class);
		List<QuotaDetailUnlockParamDto.CreditRightUnlockInfo> creditRightUnlockInfoList = new ArrayList<QuotaDetailUnlockParamDto.CreditRightUnlockInfo>();
		QuotaDetailUnlockParamDto.CreditRightUnlockInfo creditRightUnlockInfo = null;
		for (CreditDetailDto creditDetail : creditDetailDtoList) {
			creditRightUnlockInfo = new QuotaDetailUnlockParamDto.CreditRightUnlockInfo();
			creditRightUnlockInfo.setCreditId(creditDetail.getCreditCode());// 债权编号
			creditRightUnlockInfo.setTransferId(creditDetail.getTransferId());// 转让编号
			creditRightUnlockInfo.setFreeValue(creditDetail.getThisMakeCreditorValue());// 本次释放债权价值（本次转让债权价值）
			creditRightUnlockInfo.setIsWhole(CimsConstant.CREDIT_ISWHOLE);// 全部释放
			creditRightUnlockInfo.setDeliveryDate(settleDate);// 标的日期（如果标的日期为当天，日期为空）
			creditRightUnlockInfoList.add(creditRightUnlockInfo);
		}
		QuotaDetailUnlockParamDto paramDto = new QuotaDetailUnlockParamDto();
		paramDto.setQuotaType(CimsConstant.QUOTATYPE_CR);
		paramDto.setCreditRightUnlockList(creditRightUnlockInfoList);
		// 调用释放债权的接口
		logger.info("删除/重置释放债权>>>>>" + JSON.toJSONString(paramDto));
		interactImpl.quotaDetailUnlock(paramDto);
	}
	
	/**
	 * @description 新增二次购买交易流水，以及二次购买和月还关联信息
	 * @author shengzhoutao
	 * @param dealDto
	 *            二次购买交易对象
	 * @param settleDealDtoList
	 *            月还交易对象
	 * @return dealDto 二次购买交易对象
	 * @throws Exception
	 */
	private DealDto insertSecondBuyDeal(DealDto dealDto, List<DealDto> settleDealDtoList) throws Exception {
		BigDecimal planSellSum = BigDecimal.ZERO;
		BigDecimal creditorValue = BigDecimal.ZERO;
		BigDecimal deliverSum = BigDecimal.ZERO;
		BigDecimal practicalSellSum = BigDecimal.ZERO;

		String dealCode = sysAssistService.getBizNoForNewTran(CimsConstant.BIZNO_TYPE_DEAL);// 二次购买匹配债权的流水号
		TCMmCooperorgDealReleDTO cooperorgDealReleDTO = null;
		for (DealDto settleDealDto : settleDealDtoList) {
			planSellSum = planSellSum.add(settleDealDto.getPlanSellSum() == null ? BigDecimal.ZERO : settleDealDto.getPlanSellSum());
			creditorValue = creditorValue.add(settleDealDto.getSumCreditorValue() == null ? BigDecimal.ZERO : settleDealDto.getSumCreditorValue());
			deliverSum = deliverSum.add(settleDealDto.getDeliverSum() == null ? BigDecimal.ZERO : settleDealDto.getDeliverSum());
			practicalSellSum = practicalSellSum.add(settleDealDto.getPracticalSellSum() == null ? BigDecimal.ZERO : settleDealDto.getPracticalSellSum());

			cooperorgDealReleDTO = new TCMmCooperorgDealReleDTO();
			cooperorgDealReleDTO.setDealCode(dealCode);
			cooperorgDealReleDTO.setOldDealCode(settleDealDto.getDealCode());
			cooperorgDealReleDTO.setReleType(CimsConstant.RELE_TYPE_SECOND_BUY);
			cooperorgDealReleService.insertTCMmCooperorgDealRele(cooperorgDealReleDTO);
		}
		cooperorgDealReleDTO = null;
		
		dealDto.setDealCode(dealCode);// 二次购买匹配债权的流水号
		dealDto.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_CREATE);// 新建
		dealDto.setDealType(CimsConstant.DEAL_TYPE_SECOND_PURCHASE);// 交易类型:09-二次购买
		dealDto.setDeliverSum(deliverSum);// 折扣金额/返回金额
		dealDto.setPlanSellSum(planSellSum);// 预售金额
		dealDto.setPracticalSellSum(practicalSellSum);// 实售金额/实际匹配金额
		dealDto.setDealDate(new Date());// 交易日期
		dealDto.setLoanEachStatus(null);
		dealDto.setSumCreditorValue(creditorValue);// 汇总债权价值
		dealDto.setCreditReferDate(DateTimeUtils.formatDate(settleDealDtoList.get(0).getSettleDate(), "yyyy-MM-dd"));
		
		long key = dealService.saveDeal(dealDto);
		logger.info("二次购买>>主键>>>" + key);
		
		dealDto.setSumCreditorValue(practicalSellSum);// 汇总债权价值
		
		return dealDto;
	}
	
	/**
	 * @description insertCreditPackage
	 * @param dealDto
	 * @throws Exception
	 */
	private DealDto insertCreditPackage(DealDto dealDto) throws Exception {
		TCMmCreditPackageDTO creditPackage = new TCMmCreditPackageDTO();
		creditPackage.setCooperorgCode(dealDto.getCooperorgCode());
		creditPackage.setCreditPackageName(dealDto.getCreditPackageName());
		creditPackage.setContractCode(dealDto.getContractCode());
		List<TCMmCreditPackageDTO> dataList = creditPackageService.searchTCMmCreditPackage(SearchParamUtil.getSearchParam(creditPackage));
		
		if (CollectionsUtils.isEmpty(dataList)) {
			creditPackage = new TCMmCreditPackageDTO();
			creditPackage.setCooperorgCode(dealDto.getCooperorgCode());
			creditPackage.setCreditPackageName(dealDto.getCreditPackageName());
			creditPackage.setContractCode(dealDto.getContractCode());
			List<CreditPackageDto> creditPackageList = creditRightDao.searchCreditPackageForSecondCode(SearchParamUtil.getSearchParam(creditPackage));
			if (CollectionsUtils.isNotEmpty(creditPackageList)) {
				creditPackage.setBillDate(creditPackageList.get(0).getBillDate());
				creditPackage.setBillDateEnd(creditPackageList.get(0).getBillDateEnd());
				creditPackage.setRepayType(creditPackageList.get(0).getRepayType());
				creditPackage.setPlanRedeemDate(creditPackageList.get(0).getPlanRedeemDate());

				dealDto.setBillDate(creditPackageList.get(0).getBillDate());
				dealDto.setBillDateEnd(creditPackageList.get(0).getBillDateEnd());
				dealDto.setRepayType(creditPackageList.get(0).getRepayType());
			}
			creditPackageService.insertTCMmCreditPackage(creditPackage);
		} else {
			creditPackage = dataList.get(0);
			dealDto.setBillDate(creditPackage.getBillDate());
			dealDto.setBillDateEnd(creditPackage.getBillDateEnd());
			dealDto.setRepayType(creditPackage.getRepayType());
		}
		
		return dealDto;
	}

}
